package com.hj.dapp.business.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hj.dapp.business.role.model.Role;
import com.hj.dapp.business.role.service.RoleService;
import com.hj.dapp.business.role.service.RoleUserService;
import com.hj.dapp.business.user.mapper.UserMapper;
import com.hj.dapp.business.user.model.User;
import com.hj.dapp.business.user.service.UserService;
import com.hj.dapp.business.user.vo.RoleBind;
import com.hj.dapp.business.user.vo.UserInfoVO;
import com.hj.dapp.common.request.PageRequest;
import com.hj.dapp.common.util.ExpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.security.Principal;
import java.time.LocalDateTime;
import java.util.List;

import static com.hj.dapp.common.constant.CustomerConstant.*;
import static com.hj.dapp.common.constant.DictEnum.*;
import static com.hj.dapp.config.exp.BusinessErrorEnum.*;

/**
 * @author 胡奥程
 * @version 1.0
 * @date 2023/12/29
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleService roleService;
    @Autowired
    private RoleUserService roleUserService;


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        User user = userMapper.selectOne(wrapper);
        if (ObjectUtils.isEmpty(user)) {
            throw new UsernameNotFoundException("用户名不存在");
        }
        List<Role> roleList = roleService.getRoleListByUser(user.getId());
        user.setRoles(roleList);
        return user;
    }

    @Override
    public List<User> getUserList() {
        QueryWrapper<User> query = new QueryWrapper<>();
        query.eq("del_flag", NORMAL_FLAG.getValue());
        return userMapper.selectList(query);
    }

    @Override
    public void registerUser(User user, Principal principal) {
        //校验用户名是否重复
        this.validateUserName(user.getUsername());
        if (!ObjectUtils.isEmpty(principal)) {
            user.setCreateBy(principal.getName());
        }
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        //密码加盐
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        //设置默认启用
        user.setStatus(ENABLE_STATUS.getValue());
        user.setDelFlag(NORMAL_FLAG.getValue());
        user.setCreateTime(LocalDateTime.now());
        userMapper.insert(user);
    }

    @Override
    public void validateUserName(String username) {
        QueryWrapper<User> query = new QueryWrapper<>();
        query.eq("username", username);
        if (userMapper.selectCount(query)>0) {
            ExpUtil.throwExp(USER_REPEAT);
        }
    }

    @Override
    public void deleteUser(String userName, Principal principal) {
        if (!ADMIN_FLAG.getLabel().equals(principal.getName())) {
            ExpUtil.throwExp(USER_REJECT);
        }
        QueryWrapper<User> query = new QueryWrapper<>();
        query.eq("username", userName);
        User user = userMapper.selectOne(query);
        user.setDelFlag(DELETE_FLAG.getValue());
        userMapper.update(user, query);
    }

    @Override
    public void editUser(User user, Principal principal) {
        user.setDelFlag(null);
        if (!ObjectUtils.isEmpty(user.getPassword())) {
            BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }
        if (ADMIN_FLAG.getLabel().equals(user.getUsername())&&!ADMIN_FLAG.getLabel().equals(principal.getName())) {
            ExpUtil.throwExp(ADMIN_REJECT);
        }
        QueryWrapper<User> query = new QueryWrapper<>();
        if (ADMIN_FLAG.getLabel().equals(principal.getName())) {
            query.eq("id", user.getId());
        } else {
            if (!user.getUsername().equals(principal.getName())) {
                ExpUtil.throwExp(USER_REJECT);
            } else {
                query.eq("id", user.getId());
            }
        }
        user.setLastUpdateBy(principal.getName());
        user.setLastUpdateTime(LocalDateTime.now());
        userMapper.update(user, query);
    }

    @Override
    public IPage<User> pageUser(PageRequest<User> request) {
        Page<User> page = new Page<>();
        page.setSize(request.getSize());
        page.setCurrent(request.getCurrent());
        QueryWrapper<User> query = new QueryWrapper<>();
        query.eq("del_flag",NORMAL_FLAG.getValue());
        if (!ObjectUtils.isEmpty(request.getQuery())) {
            if (!ObjectUtils.isEmpty(request.getQuery().getUsername())) {
                query.like("username", request.getQuery().getUsername());
            }
            if (!ObjectUtils.isEmpty(request.getQuery().getRealName())) {
                query.like("real_name", request.getQuery().getRealName());
            }
            if (!ObjectUtils.isEmpty(request.getQuery().getPhone())) {
                query.like("phone", request.getQuery().getPhone());
            }
            if (!ObjectUtils.isEmpty(request.getQuery().getGender())) {
                query.like("gender", request.getQuery().getGender());
            }

        }
        return userMapper.selectPage(page, query);
    }

    @Override
    public UserInfoVO userInfo(Principal principal) {
        List<Role> roles = roleService.getRoleListByUser(principal.getName());
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", principal.getName());
        User user = userMapper.selectOne(wrapper);
        UserInfoVO vo = new UserInfoVO();
        vo.setUser(user);
        vo.setRoles(roles);
        return vo;
    }

    @Override
    public User getUser(String userId) {
        return userMapper.selectById(userId);
    }

    @Override
    public User getUserByUserName(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public List<Role> getRoleList(Long  userId) {
        return roleService.getRoleListByUser(userId);
    }

    @Override
    public void bindRoleRel(RoleBind roleBind) {
        roleUserService.deleteRoleRel(roleBind.getUserId());
        roleBind.getRoles().forEach(n->{
            roleUserService.bindRoleRel(roleBind.getUserId(),n);
        });
    }

    @Override
    public List<User> getDesignerList() {

        return userMapper.getPostList(DESIGNER_ROLE_ID);
    }

    @Override
    public User getUserById(Long id) {
        return userMapper.selectById(id);
    }

    @Override
    public List<User> getSupervisorList() {
        return userMapper.getPostList(SUPERVISOR_ROLE_ID);
    }

    @Override
    public List<User> getReviewerList() {
        return userMapper.getPostList(REVIEWER_ROLE_ID);
    }
}
